// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成
package com.fowo.api.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fowo.api.common.model.IdListPo;
import com.fowo.api.common.model.IdPo;
import com.fowo.api.common.model.OptionItem;
import com.fowo.api.common.model.R;
import com.fowo.api.common.util.ResponseUtils;
import com.fowo.api.entity.StockIn;
import com.fowo.api.model.stock.in.StockInCustomUpdateStockInStatusVo;
import com.fowo.api.model.stock.in.StockInItemVo;
import com.fowo.api.model.stock.in.StockInSearchParamPo;
import com.fowo.api.model.stock.in.StockInVo;
import com.fowo.api.service.StockInService;
import com.fowo.api.user.model.JwtUserInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "入库单")
@RequestMapping("/api/stock-in")
@RestController
public class StockInController {

  @Resource
  private StockInService service;

  @Operation(summary = "查询结果")
  @GetMapping
  public R<List<StockInItemVo>> search(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.search(search));
  }

  @Operation(summary = "快速查询选项(有缓存)")
  @GetMapping("options")
  public R<List<OptionItem<StockInItemVo>>> searchOptions(
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchOptions(search));
  }

  @Operation(summary = "查询最后更新时间")
  @GetMapping("lastUpdateTime")
  public R<Date> searchLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchLastUpdateTime(search));
  }

  @Operation(summary = "获取满足搜索条件的统计信息")
  @GetMapping("statistical")
  public R<?> searchForStatistical(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.searchForStatistical(search));
  }

  @Operation(summary = "获取分页查询结果")
  @GetMapping("page")
  public R<Page<StockInItemVo>> getPage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageSearch(search));
  }

  @Operation(summary = "获取包括子表的查询结果")
  @GetMapping("page-with-child")
  public R<Page<?>> getPageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageWithChildSearch(search));
  }

  @Operation(summary = "仅获取子表的查询结果")
  @GetMapping("page-only-child/{parentId}")
  public R<Page<?>> getPageOnlyChild(
    @PathVariable Long parentId,
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.pageOnlyChildSearch(parentId, search));
  }

  @Operation(summary = "查询是否后台下载")
  @GetMapping("getBackgroundExportFlag")
  public R<Boolean> getBackgroundExportFlag(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.getBackgroundExportFlag(search));
  }

  @Operation(summary = "获取详情")
  @GetMapping("{id}")
  public R<StockInVo> getVoById(@PathVariable Long id) {
    return R.data(() -> service.getVoById(id));
  }

  @Operation(summary = "获取采购员相关的编号列表")
  @GetMapping("cg-realname/{texts}/ids")
  public R<List<Long>> getIdsByCgRealname(@PathVariable String texts) {
    List<String> nameList = Arrays
      .stream(texts.split(","))
      .collect(Collectors.toList());
    return R.data(() -> service.getIdsByCgRealname(nameList));
  }

  @Operation(summary = "获取编号相关的采购员列表")
  @GetMapping("cg-realname/{ids}")
  public R<List<String>> getVoById(@PathVariable String ids) {
    List<Long> idList = Arrays
      .asList(ids.split(","))
      .stream()
      .map(Long::valueOf)
      .collect(Collectors.toList());
    return R.data(() -> service.getCgRealnameByIds(idList));
  }

  @PreAuthorize("@am.canAccess('stockInCreate')")
  @Operation(summary = "新增")
  @PostMapping
  public R<Long> create(@Validated @RequestBody StockInVo model) {
    return R.data(() -> service.create(model));
  }

  @PreAuthorize("@am.canAccess('stockInEdit')")
  @Operation(summary = "更新")
  @PutMapping
  public R update(@RequestBody StockInVo model) {
    return R.run(() -> service.update(model));
  }

  @PreAuthorize("@am.canAccess('stockInEdit')")
  @Operation(summary = "编辑更新")
  @PutMapping("edit")
  public R updateForEdit(@RequestBody StockInVo model) {
    return R.run(() -> service.updateForEdit(model));
  }

  @PreAuthorize("@am.canAccess('stockInDelete')")
  @Operation(summary = "删除")
  @DeleteMapping("{id}")
  public R delete(@PathVariable Long id) {
    return R.run(() -> service.delete(id));
  }

  @PreAuthorize("@am.canAccess('stockInDelete')")
  @Operation(summary = "批量删除")
  @DeleteMapping("batch")
  public R batchDelete(@RequestBody IdListPo po) {
    return R.run(() -> service.batchDelete(po.getIds()));
  }

  @Operation(summary = "导出")
  @GetMapping("export")
  @PreAuthorize("@am.canAccess('stockInExport')")
  public void export(
    @RequestParam(name = "template", required = false) Long templateId,
    StockInSearchParamPo search,
    HttpServletResponse response
  ) throws Exception {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    service.export(templateId, search, response);
  }

  @PreAuthorize("@am.canAccess('stockInPushLingXing')")
  @Operation(summary = "推送领星")
  @PostMapping("pushLingXing")
  public R pushLingXing(@RequestBody IdPo po) {
    return R.run(() -> service.pushLingXing(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInCustCancelAudit')")
  @Operation(summary = "撤销")
  @PostMapping("custCancelAudit")
  public R custCancelAudit(@RequestBody IdPo idPo) {
    return R.run(() -> service.custCancelAudit(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInRefer')")
  @Operation(summary = "提交")
  @PostMapping("refer")
  public R refer(@RequestBody IdPo po) {
    return R.run(() -> service.refer(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInConfirmWarehouse')")
  @Operation(summary = "确认入库")
  @PostMapping("confirmWarehouse")
  public R confirmWarehouse(@RequestBody IdPo po) {
    return R.run(() -> service.confirmWarehouse(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInResubmit')")
  @Operation(summary = "重新提交")
  @PostMapping("resubmit")
  public R resubmit(@RequestBody IdListPo po) {
    return R.run(() -> service.resubmit(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockInRevokeWarehousing')")
  @Operation(summary = "批量撤销")
  @PostMapping("revokeWarehousing")
  public R revokeWarehousing(@RequestBody IdListPo po) {
    return R.run(() -> service.revokeWarehousing(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockInCustSubmitOrder')")
  @Operation(summary = "提交")
  @PostMapping("custSubmitOrder")
  public R custSubmitOrder(@RequestBody IdListPo po) {
    return R.run(() -> service.custSubmitOrder(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockInPushprocess')")
  @Operation(summary = "生成加工单")
  @PostMapping("pushprocess")
  public R pushprocess(@RequestBody IdListPo po) {
    return R.run(() -> service.pushprocess(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockInApplyInBatchStorage')")
  @Operation(summary = "批量审核")
  @PostMapping("applyInBatchStorage")
  public R applyInBatchStorage(@RequestBody IdListPo po) {
    return R.run(() -> service.applyInBatchStorage(po.getIds()));
  }

  @PreAuthorize("@am.canAccess('stockInRuku')")
  @Operation(summary = "入库")
  @PostMapping("ruku")
  public R ruku(@RequestBody IdPo idPo) {
    return R.run(() -> service.ruku(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInPushStockOther')")
  @Operation(summary = "下推其他出库单")
  @PostMapping("pushStockOther")
  public R pushStockOther(@RequestBody IdPo po) {
    return R.run(() -> service.pushStockOther(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInInventoryTurnover')")
  @Operation(summary = "库存流转")
  @PostMapping("inventoryTurnover")
  public R inventoryTurnover(@RequestBody IdPo idPo) {
    return R.run(() -> service.inventoryTurnover(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInRukucipin')")
  @Operation(summary = "入库次品")
  @PostMapping("rukucipin")
  public R rukucipin(@RequestBody IdPo idPo) {
    return R.run(() -> service.rukucipin(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInPushSellOrder')")
  @Operation(summary = "下推销售出库单")
  @PostMapping("pushSellOrder")
  public R pushSellOrder(@RequestBody IdPo po) {
    return R.run(() -> service.pushSellOrder(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInRuku3')")
  @Operation(summary = "入库待检量")
  @PostMapping("ruku3")
  public R ruku3(@RequestBody IdPo idPo) {
    return R.run(() -> service.ruku3(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInCancelWarehousing')")
  @Operation(summary = "撤销")
  @PostMapping("cancelWarehousing")
  public R cancelWarehousing(@RequestBody IdPo idPo) {
    return R.run(() -> service.cancelWarehousing(idPo.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInPushPayable')")
  @Operation(summary = "下推应付单")
  @PostMapping("pushPayable")
  public R pushPayable(@RequestBody IdPo po) {
    return R.run(() -> service.pushPayable(po.getId()));
  }

  @PreAuthorize("@am.canAccess('stockInSyncWarehousingOrder')")
  @Operation(summary = "同步领星入库单")
  @PostMapping("syncWarehousingOrder")
  public R syncWarehousingOrder() {
    return R.run(() -> service.syncWarehousingOrder());
  }

  @PreAuthorize("@am.canAccess('stockInCustSmtStockin')")
  @Operation(summary = "提交表单")
  @PostMapping("custSmtStockin")
  public R custSmtStockin(@RequestBody IdPo po) {
    return R.run(() -> service.custSmtStockin(po.getId()));
  }

  /**
   * 视图选项卡标题上显示计数
   */
  @Operation(summary = "视图选项卡标题上显示计数")
  @GetMapping("getTabHeaderShowTotal")
  public R<Map> getTabHeaderShowTotal() {
    return R.data(() -> service.getTabHeaderShowTotal());
  }

  @Operation(summary = "全部")
  @GetMapping("entire")
  public R<List<StockInItemVo>> entire(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.entire(search));
  }

  @Operation(summary = "全部分页")
  @GetMapping("entirePage")
  public R<Page<StockInItemVo>> entirePage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.entirePage(search));
  }

  @Operation(summary = "全部包括子表的查询结果")
  @GetMapping("entirePage-with-child")
  public R<Page<?>> entirePageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.entirePageWithChildSearch(search));
  }

  @Operation(summary = "全部最后更新时间")
  @GetMapping("entireLastUpdateTime")
  public R<Date> entireLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.entireLastUpdateTime(search));
  }

  @Operation(summary = "待提交")
  @GetMapping("changes-to-be-committed")
  public R<List<StockInItemVo>> changesToBeCommitted(
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommitted(search));
  }

  @Operation(summary = "待提交分页")
  @GetMapping("changes-to-be-committedPage")
  public R<Page<StockInItemVo>> changesToBeCommittedPage(
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommittedPage(search));
  }

  @Operation(summary = "待提交包括子表的查询结果")
  @GetMapping("changes-to-be-committedPage-with-child")
  public R<Page<?>> changesToBeCommittedPageWithChild(
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.changesToBeCommittedPageWithChildSearch(search));
  }

  @Operation(summary = "待提交最后更新时间")
  @GetMapping("changes-to-be-committedLastUpdateTime")
  public R<Date> changesToBeCommittedLastUpdateTime(
    StockInSearchParamPo search
  ) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.changesToBeCommittedLastUpdateTime(search));
  }

  @Operation(summary = "待入库")
  @GetMapping("stock-pending")
  public R<List<StockInItemVo>> stockPending(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.stockPending(search));
  }

  @Operation(summary = "待入库分页")
  @GetMapping("stock-pendingPage")
  public R<Page<StockInItemVo>> stockPendingPage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.stockPendingPage(search));
  }

  @Operation(summary = "待入库包括子表的查询结果")
  @GetMapping("stock-pendingPage-with-child")
  public R<Page<?>> stockPendingPageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.stockPendingPageWithChildSearch(search));
  }

  @Operation(summary = "待入库最后更新时间")
  @GetMapping("stock-pendingLastUpdateTime")
  public R<Date> stockPendingLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.stockPendingLastUpdateTime(search));
  }

  @Operation(summary = "已完成")
  @GetMapping("completed")
  public R<List<StockInItemVo>> completed(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.completed(search));
  }

  @Operation(summary = "已完成分页")
  @GetMapping("completedPage")
  public R<Page<StockInItemVo>> completedPage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.completedPage(search));
  }

  @Operation(summary = "已完成包括子表的查询结果")
  @GetMapping("completedPage-with-child")
  public R<Page<?>> completedPageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.completedPageWithChildSearch(search));
  }

  @Operation(summary = "已完成最后更新时间")
  @GetMapping("completedLastUpdateTime")
  public R<Date> completedLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.completedLastUpdateTime(search));
  }

  @Operation(summary = "已撤销")
  @GetMapping("undone")
  public R<List<StockInItemVo>> undone(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undone(search));
  }

  @Operation(summary = "已撤销分页")
  @GetMapping("undonePage")
  public R<Page<StockInItemVo>> undonePage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undonePage(search));
  }

  @Operation(summary = "已撤销包括子表的查询结果")
  @GetMapping("undonePage-with-child")
  public R<Page<?>> undonePageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.undonePageWithChildSearch(search));
  }

  @Operation(summary = "已撤销最后更新时间")
  @GetMapping("undoneLastUpdateTime")
  public R<Date> undoneLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.undoneLastUpdateTime(search));
  }

  @Operation(summary = "已驳回")
  @GetMapping("reject")
  public R<List<StockInItemVo>> reject(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.reject(search));
  }

  @Operation(summary = "已驳回分页")
  @GetMapping("rejectPage")
  public R<Page<StockInItemVo>> rejectPage(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.rejectPage(search));
  }

  @Operation(summary = "已驳回包括子表的查询结果")
  @GetMapping("rejectPage-with-child")
  public R<Page<?>> rejectPageWithChild(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(service.rejectPageWithChildSearch(search));
  }

  @Operation(summary = "已驳回最后更新时间")
  @GetMapping("rejectLastUpdateTime")
  public R<Date> rejectLastUpdateTime(StockInSearchParamPo search) {
    JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
    if (jwtUserInfo != null) {
      search.setCurrentUserId(jwtUserInfo.getUserId());
    }
    return R.data(() -> service.rejectLastUpdateTime(search));
  }

  @Operation(summary = "更新入库单单据状态")
  @PutMapping("CustomUpdateStockInStatus")
  public R<?> customUpdateStockInStatus(
    @Validated @RequestBody StockInCustomUpdateStockInStatusVo customUpdateStockInStatusVo
  ) {
    return R.run(() ->
      service.customUpdateStockInStatus(customUpdateStockInStatusVo)
    );
  }
}
